package com.chenwenxuan.sync.utils;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;

import org.apache.commons.lang3.time.FastDateFormat;
import org.ini4j.InvalidFileFormatException;
import org.ini4j.Profile;
import org.ini4j.Wini;

public class HolidayConfig {
	
	private String path;
	private long lastHolidayFileTimestamp;
	private Set <String> holidaySet;
	private Set <String> workdaySet;
	private boolean workdayfirst;
	
	public HolidayConfig() {
		
	}
	
	public boolean isHoliday(Date date) {
		String str = FastDateFormat.getInstance("yyyyMMdd").format(date);
		return holidaySet == null ? false :holidaySet.contains(str);
	}
	
	public boolean isWorkDay(Date date) {
		String str = FastDateFormat.getInstance("yyyyMMdd").format(date);
		return workdaySet == null ? false :workdaySet.contains(str);
	}
	
	public void refresh() throws InvalidFileFormatException, IOException, ParseException {
		
		File f = new File(path);
		
		long last = f.lastModified();
		
		if ( last == lastHolidayFileTimestamp) {
			return;
		}
		
		lastHolidayFileTimestamp = last;
		
		Wini ini = new Wini(new File(path));
		Set<Entry<String, Profile.Section>> years = ini.entrySet();
		Set <String> newHolidaySet = new TreeSet<String>();
		Set <String> newWorkdaySet = new TreeSet<String>();
		
		for ( Iterator <Entry<String, Profile.Section>>  it = years.iterator(); it.hasNext(); ) {
			
			Entry<String, Profile.Section> entry = it.next();
			String year = entry.getKey();
			int iyear = 0;
			
			try {
				iyear = Integer.parseInt(year);
			} catch (Exception e) {
			}
			
			if ( iyear < 2000 || iyear > 2099) {
				continue;
			}
			
			Profile.Section section = entry.getValue();
			String holiday = section.get("holiday");
			String workday = section.get("workday");
			
			List <String> holidayList = parseDayline(iyear, holiday);
			List <String> workdayList = parseDayline(iyear, workday);
			
			newHolidaySet.addAll(holidayList);
			newWorkdaySet.addAll(workdayList);
		}
		
		holidaySet = newHolidaySet;
		workdaySet = newWorkdaySet;
		
	}
	
	private List <String> parseDayline(int year, String dayline) throws ParseException {
		
		if ( dayline == null || dayline.trim().isEmpty() ) {
			return new ArrayList<String>(0);
		}
		
		List <String> dateList = new ArrayList<String>();
		SimpleDateFormat format = new SimpleDateFormat("M.d");
		
		SimpleDateFormat parsedFormat = new SimpleDateFormat("MMdd");
		
		String [] groups = dayline.split(",");
		
		for ( String group : groups ) {
			String [] days = group.split("-");
			if ( days.length == 1 ) {
				
				if ( days[0] == null || days[0].trim().isEmpty() )
					continue;
				
				dateList.add(year + parsedFormat.format(format.parse(days[0])));
				
			} else if ( days.length == 2 ) {
				
				String start = days[0];
				String end = days[1];
				
				for ( String day : days ) {
					if ( day == null || day.trim().isEmpty() )
						continue;
				}
				
				Calendar cs = Calendar.getInstance();
				cs.setTime(format.parse(start)); 
				
				Calendar ce = Calendar.getInstance();
				ce.setTime(format.parse(end));
				
				for ( Calendar current = cs; !current.after(ce); current.add(Calendar.DAY_OF_MONTH, 1) ) {
					dateList.add(year + parsedFormat.format(current.getTime()));
				}
				
				
			}
		}
		return dateList;
		
	}

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public boolean isWorkdayfirst() {
		return workdayfirst;
	}

	public void setWorkdayfirst(boolean workdayfirst) {
		this.workdayfirst = workdayfirst;
	}

}
